ENTRY(start)
jmp __start
-
- .align 4
-
+
+ .org 0x004
/*** MULTIBOOT HEADER ****/
/* Magic number indicating a Multiboot header. */
.long 0x1BADB002
.long 0x00000002
/* Checksum: must be the negated sum of the first two fields. */
.long -0x1BADB004
-
-bad_cpu_msg:
+
+ .org 0x010
.asciz "Bad CPU: does not support 64-bit (long) mode."
bad_cpu:
- mov $SYMBOL_NAME(bad_cpu_msg)-__PAGE_OFFSET,%esi
+ mov $0x100010,%esi # Error message
mov $0xB8000,%edi # VGA framebuffer
1: mov (%esi),%bl
test %bl,%bl # Terminate on '\0' sentinel
jmp 1b
__start:
+ cld
+ cli
+
/* Set up a few descriptors: on entry only CS is guaranteed good. */
- lgdt %cs:nopaging_gdt_descr-__PAGE_OFFSET
+ lgdt %cs:0x1001f0
mov $(__HYPERVISOR_DS),%ecx
mov %ecx,%ds
mov %ecx,%es
- mov %ecx,%fs
- mov %ecx,%gs
- ljmp $(__HYPERVISOR_CS32),$(1f)-__PAGE_OFFSET
-1: lss stack_start-__PAGE_OFFSET,%esp
-
- /* Reset EFLAGS (subsumes CLI and CLD). */
- pushl $0
- popf
/* We begin by interrogating the CPU for the presence of long mode. */
mov $0x80000000,%eax
/* Set up FPU. */
fninit
- /* Set up CR4, except global flag which Intel requires should be */
- /* left until after paging is enabled (IA32 Manual Vol. 3, Sec. 2.5) */
- mov mmu_cr4_features-__PAGE_OFFSET,%ecx
- and $0x7f,%cl # CR4.PGE (global enable)
+ /* Enable PAE in CR4. */
+ mov $0x20,%ecx # X86_CR4_PAE
mov %ecx,%cr4
-
+
cmp $(SECONDARY_CPU_FLAG),%ebx
je start_paging
- add $__PAGE_OFFSET,%ebx
- push %ebx /* Multiboot info struct */
- push %eax /* Multiboot magic value */
-
- /* Initialize BSS (no nasty surprises!) */
- mov $__bss_start-__PAGE_OFFSET,%edi
- mov $_end-__PAGE_OFFSET,%ecx
- sub %edi,%ecx
- xor %eax,%eax
- rep stosb
-
- /* Initialize low and high mappings of all memory with 4MB pages */
- mov $idle_pg_table-__PAGE_OFFSET,%edi
- mov $0x1e3,%eax /* PRESENT+RW+A+D+4MB+GLOBAL */
-1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
- stosl /* low mapping */
- add $(1<<L2_PAGETABLE_SHIFT),%eax
- cmp $DIRECTMAP_PHYS_END+0x1e3,%eax
- jne 1b
+ mov %ebx,0x1001e0 /* Multiboot info struct */
+ mov %eax,0x1001e4 /* Multiboot magic value */
- /* Initialise IDT with simple error defaults. */
- lea ignore_int,%edx
- mov $(__HYPERVISOR_CS64 << 16),%eax
- mov %dx,%ax /* selector = 0x0010 = cs */
- mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
- lea SYMBOL_NAME(idt_table)-__PAGE_OFFSET,%edi
- mov $256,%ecx
-1: mov %eax,(%edi)
- mov %edx,4(%edi)
- add $8,%edi
+ /* Initialize mappings of 1GB of memory. */
+ mov $0x103000,%edi /* idle_pg_table_l2 */
+ mov $0x1e3,%eax /* PRESENT+RW+A+D+PSE+GLOBAL */
+ mov $512,%ecx
+1: stosl
+ add $0x200000,%eax
loop 1b
start_paging:
- mov $idle_pg_table-__PAGE_OFFSET,%eax
+ mov $0x101000,%eax /* idle_pg_table */
mov %eax,%cr3
mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
mov %eax,%cr0
jmp 1f
1: /* Now in compatibility mode. Long-jump into 64-bit mode. */
- ljmp $(__HYPERVISOR_CS64),$1f
+ ljmp $(__HYPERVISOR_CS64),$0x1000e0
.code64
-1: /* Install relocated selectors (FS/GS unused). */
- lgdt gdt_descr
+ .org 0x00e0
+
+ /* Jump to high mappings. */
+ mov high_start(%rip),%rax
+ push %rax
+ ret
+__high_start:
+
+ /* Install relocated selectors (FS/GS unused). */
+ lgdt gdt_descr(%rip)
mov $(__HYPERVISOR_DS),%ecx
mov %ecx,%ds
mov %ecx,%es
mov %ecx,%ss
-1: /* Paging enabled, so we can now enable GLOBAL mappings in CR4. */
- mov mmu_cr4_features,%rcx
+
+ /* Enable full CR4 features. */
+ mov mmu_cr4_features(%rip),%rcx
mov %rcx,%cr4
- /* Relocate ESP */
- add $__PAGE_OFFSET,%esp
- lidt idt_descr
+ mov stack_start(%rip),%rsp
+
+ /* Reset EFLAGS (subsumes CLI and CLD). */
+ pushq $0
+ popf
+
+ lidt idt_descr(%rip)
cmp $(SECONDARY_CPU_FLAG),%ebx
je start_secondary
+ /* Initialize BSS (no nasty surprises!) */
+ lea __bss_start(%rip),%rdi
+ lea _end(%rip),%rcx
+ sub %rdi,%rcx
+ xor %rax,%rax
+ rep stosb
+
+ /* Initialise IDT with simple error defaults. */
+ lea ignore_int(%rip),%rdx
+ mov $(__HYPERVISOR_CS64 << 16),%eax
+ mov %dx,%ax /* selector = 0x0010 = cs */
+ mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
+ lea idt_table(%rip),%rdi
+ mov $256,%rcx
+1: mov %eax,(%rdi)
+ mov %edx,4(%rdi)
+ add $8,%rdi
+ loop 1b
+
+ xor %rax,%rax
+ mov 0x1001e0,%eax /* Multiboot info struct */
+ lea start(%rip),%rbx
+ sub $0x100000,%rbx
+ add %rbx,%rax
+ push %rax
+ xor %rax,%rax
+ mov 0x1001e4,%eax /* Multiboot magic value */
+ push %rax
+
/* Call into main C routine. This should never return.*/
call cmain
ud2 /* Force a panic (invalid opcode). */
mov $(__HYPERVISOR_DS),%eax
mov %eax,%ds
mov %eax,%es
- pushq $int_msg
+ lea int_msg(%rip),%rax
+ push %rax
call SYMBOL_NAME(printf)
1: jmp 1b
.code32
- .align 8
-/*** STACK LOCATION ***/
-
-ENTRY(stack_start)
- .long SYMBOL_NAME(cpu0_stack) + 8100 - __PAGE_OFFSET
- .long __HYPERVISOR_DS
-
/*** DESCRIPTOR TABLES ***/
.globl SYMBOL_NAME(idt)
.globl SYMBOL_NAME(gdt)
- .word 0
-idt_descr:
- .word 256*8-1
-SYMBOL_NAME(idt):
- .long SYMBOL_NAME(idt_table)
-
- .word 0
-gdt_descr:
- .word (LAST_RESERVED_GDT_ENTRY*8)+7
-SYMBOL_NAME(gdt):
- .long SYMBOL_NAME(gdt_table) /* gdt base */
-
- .word 0
-nopaging_gdt_descr:
+ .org 0x1f0
.word (LAST_RESERVED_GDT_ENTRY*8)+7
- .long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET
+ .long 0x100200 # gdt_table
- .align 64
+ .org 0x200
ENTRY(gdt_table)
.fill FIRST_RESERVED_GDT_ENTRY,8,0
.quad 0x0000000000000000 /* unused */
.quad 0x00cffa000000ffff /* 0x0823 ring 3 code, compatibility */
.quad 0x00affa000000ffff /* 0x082b ring 3 code, 64-bit mode */
.quad 0x00cff2000000ffff /* 0x0833 ring 3 data */
- .quad 0x0000000000000000 /* unused */
- .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
+ .quad 0x0000000000000000 /* unused */
+ .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
+
+ .word 0
+gdt_descr:
+ .word (LAST_RESERVED_GDT_ENTRY*8)+7
+SYMBOL_NAME(gdt):
+ .quad SYMBOL_NAME(gdt_table)
+
+ .word 0
+idt_descr:
+ .word 256*8-1
+SYMBOL_NAME(idt):
+ .quad SYMBOL_NAME(idt_table)
+ENTRY(stack_start)
+ .quad SYMBOL_NAME(cpu0_stack) + 8100 - __PAGE_OFFSET
+
+high_start:
+ .quad __high_start
+
.org 0x1000
-ENTRY(idle_pg_table) # Initial page directory is 4kB
+ENTRY(idle_pg_table)
+ENTRY(idle_pg_table_4)
+ .quad 0x0000000000102007 # PML4[0]
+ .fill 261,8,0
+ .quad 0x0000000000102007 # PML4[262]
.org 0x2000
-ENTRY(cpu0_stack) # Initial stack is 8kB
+ENTRY(idle_pg_table_l3)
+ .quad 0x0000000000103007
+ .org 0x3000
+ENTRY(idle_pg_table_l2)
.org 0x4000
+ENTRY(cpu0_stack) # Initial stack is 8kB
+ .org 0x6000
ENTRY(stext)
ENTRY(_stext)
+
+.globl map_domain_mem, unmap_domain_mem, ret_from_intr
+map_domain_mem:
+unmap_domain_mem:
+ret_from_intr:
+#undef machine_to_phys_mapping
+.globl copy_to_user, set_intr_gate, die, machine_to_phys_mapping
+copy_to_user:
+set_intr_gate:
+die:
+machine_to_phys_mapping:
+.globl copy_from_user, show_registers, __set_fixmap, do_iopl, check_descriptor
+copy_from_user:
+show_registers:
+__set_fixmap:
+do_iopl:
+check_descriptor:
+.globl set_gdt, idt_table, copy_user_generic, memcmp, idt_tables, new_thread
+set_gdt:
+idt_table:
+copy_user_generic:
+memcmp:
+idt_tables:
+new_thread:
+.globl switch_to, continue_nonidle_task, __get_user_1, paging_init, trap_init
+switch_to:
+continue_nonidle_task:
+__get_user_1:
+paging_init:
+trap_init:
+.globl __get_user_8, zap_low_mappings, set_debugreg
+__get_user_8:
+zap_low_mappings:
+set_debugreg:
+
+